"""
库存管理相关的API
包括库存记录、库存变更等功能
"""
from flask import request, jsonify, current_app
from flask_jwt_extended import jwt_required, current_user
from sqlalchemy.exc import SQLAlchemyError
from marshmallow import ValidationError
from sqlalchemy import func

from app.extensions import db
from app.models.inventory import InventoryRecord, InventoryType
from app.models.product import Product, ProductVariant
from app.schemas.inventory import InventoryRecordSchema
from app.utils.errors import NotFoundError, BadRequestError, ForbiddenError
from app.api.v1 import api_v1

@api_v1.route('/inventory/records', methods=['GET'])
@jwt_required()
def get_inventory_records():
    """获取库存记录列表"""
    # 非管理员不能查看库存记录
    if not current_user.is_admin:
        raise ForbiddenError("权限不足，只有管理员可以查看库存记录")
    
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 20, type=int)
    product_id = request.args.get('product_id', type=int)
    variant_id = request.args.get('variant_id', type=int)
    record_type = request.args.get('type')
    
    # 构建查询
    query = InventoryRecord.query
    
    if product_id:
        query = query.filter_by(product_id=product_id)
    
    if variant_id:
        query = query.filter_by(variant_id=variant_id)
    
    if record_type:
        query = query.filter_by(type=record_type)
    
    # 分页
    pagination = query.order_by(InventoryRecord.created_at.desc()).paginate(page=page, per_page=per_page)
    
    # 预加载关联数据
    records = pagination.items
    result = []
    for record in records:
        data = record.to_dict()
        
        # 添加产品名称
        if record.product_id:
            product = Product.query.get(record.product_id)
            if product:
                data['product_name'] = product.name
        
        # 添加变体规格
        if record.variant_id:
            variant = ProductVariant.query.get(record.variant_id)
            if variant:
                data['variant_specs'] = variant.specifications
        
        # 添加操作人员名称
        if record.operator_id:
            from app.models.user import User
            user = User.query.get(record.operator_id)
            if user:
                data['operator_name'] = user.username
        
        result.append(data)
    
    return jsonify({
        "total": pagination.total,
        "pages": pagination.pages,
        "page": page,
        "per_page": per_page,
        "records": result
    }), 200

@api_v1.route('/inventory/records/<int:record_id>', methods=['GET'])
@jwt_required()
def get_inventory_record(record_id):
    """获取库存记录详情"""
    # 非管理员不能查看库存记录
    if not current_user.is_admin:
        raise ForbiddenError("权限不足，只有管理员可以查看库存记录")
    
    record = InventoryRecord.query.get_or_404(record_id)
    data = record.to_dict()
    
    # 添加产品名称
    if record.product_id:
        product = Product.query.get(record.product_id)
        if product:
            data['product_name'] = product.name
    
    # 添加变体规格
    if record.variant_id:
        variant = ProductVariant.query.get(record.variant_id)
        if variant:
            data['variant_specs'] = variant.specifications
    
    # 添加操作人员名称
    if record.operator_id:
        from app.models.user import User
        user = User.query.get(record.operator_id)
        if user:
            data['operator_name'] = user.username
    
    return jsonify(data), 200

@api_v1.route('/inventory/records', methods=['POST'])
@jwt_required()
def create_inventory_record():
    """创建库存记录"""
    # 非管理员不能创建库存记录
    if not current_user.is_admin:
        raise ForbiddenError("权限不足，只有管理员可以创建库存记录")
    
    data = request.get_json()
    
    if not data:
        raise BadRequestError("请求参数为空")
    
    # 验证数据
    schema = InventoryRecordSchema(context={
        'product_id': data.get('product_id'),
        'variant_id': data.get('variant_id'),
        'type': data.get('type')
    })
    try:
        # 使用schema验证数据
        validated_data = schema.load(data)
    except ValidationError as e:
        return jsonify({"msg": "数据验证错误", "errors": e.messages}), 400
    
    # 检查商品和变体是否存在
    product = None
    variant = None
    
    if 'product_id' in data and data['product_id']:
        product = Product.query.get(data['product_id'])
        if not product:
            return jsonify({"msg": "商品不存在"}), 400
    
    if 'variant_id' in data and data['variant_id']:
        variant = ProductVariant.query.get(data['variant_id'])
        if not variant:
            return jsonify({"msg": "商品变体不存在"}), 400
    
    # 计算库存余量
    if variant:
        current_stock = variant.stock
    elif product:
        current_stock = product.stock
    else:
        return jsonify({"msg": "必须指定商品或变体"}), 400
    
    # 根据操作类型修改库存
    if data['type'] in [InventoryType.IN.value, InventoryType.INIT.value, InventoryType.RESERVE.value]:
        new_stock = current_stock + data['quantity']
    elif data['type'] in [InventoryType.OUT.value, InventoryType.RELEASE.value]:
        # 对于出库和释放操作，数量应为正数，但在库存中减少
        new_stock = current_stock - data['quantity']
        if new_stock < 0:
            return jsonify({"msg": "库存不足"}), 400
    elif data['type'] == InventoryType.ADJUST.value:
        # 直接设置为新数量
        new_stock = data['quantity']
    else:
        return jsonify({"msg": "无效的操作类型"}), 400
    
    # 创建库存记录
    record = InventoryRecord(
        product_id=data.get('product_id'),
        variant_id=data.get('variant_id'),
        type=data['type'],
        quantity=data['quantity'],
        balance=new_stock,
        notes=data.get('notes'),
        operator_id=current_user.id
    )
    
    # 更新商品或变体的库存
    if variant:
        variant.stock = new_stock
    else:
        product.stock = new_stock
    
    try:
        db.session.add(record)
        db.session.commit()
    except SQLAlchemyError as e:
        db.session.rollback()
        current_app.logger.error(f"创建库存记录失败: {str(e)}")
        return jsonify({"msg": "创建库存记录失败", "error": str(e)}), 500
    
    return jsonify({
        "msg": "库存记录创建成功",
        "record": record.to_dict()
    }), 201

@api_v1.route('/inventory/stock', methods=['GET'])
@jwt_required()
def get_stock_summary():
    """获取库存概览"""
    product_id = request.args.get('product_id', type=int)
    
    if product_id:
        # 获取单个商品的库存
        product = Product.query.get_or_404(product_id)
        variants = ProductVariant.query.filter_by(product_id=product_id).all()
        
        # 获取该商品的入库和出库总量
        total_in = db.session.query(func.sum(InventoryRecord.quantity)).filter(
            InventoryRecord.product_id == product_id,
            InventoryRecord.type.in_([InventoryType.IN.value, InventoryType.INIT.value])
        ).scalar() or 0
        
        total_out = db.session.query(func.sum(InventoryRecord.quantity)).filter(
            InventoryRecord.product_id == product_id,
            InventoryRecord.type == InventoryType.OUT.value
        ).scalar() or 0
        
        # 获取最后更新时间
        last_record = InventoryRecord.query.filter_by(product_id=product_id).order_by(InventoryRecord.created_at.desc()).first()
        last_update = last_record.created_at if last_record else None
        
        result = {
            "product_id": product.id,
            "product_name": product.name,
            "stock": product.stock,
            "variants": [
                {
                    "id": variant.id,
                    "sku": variant.sku,
                    "specifications": variant.specifications,
                    "stock": variant.stock
                } for variant in variants
            ],
            "total_in": total_in,
            "total_out": total_out,
            "last_update": last_update.isoformat() if last_update else None
        }
        
        return jsonify(result), 200
    else:
        # 获取所有商品的库存概览
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 20, type=int)
        low_stock = request.args.get('low_stock', type=int)
        
        query = Product.query
        
        # 过滤库存不足的商品
        if low_stock:
            query = query.filter(Product.stock <= low_stock)
        
        # 分页
        pagination = query.order_by(Product.name).paginate(page=page, per_page=per_page)
        
        result = []
        for product in pagination.items:
            # 获取产品变体数量
            variant_count = ProductVariant.query.filter_by(product_id=product.id).count()
            
            # 构建结果
            item = {
                "product_id": product.id,
                "product_name": product.name,
                "sku": product.sku,
                "stock": product.stock,
                "variant_count": variant_count
            }
            
            result.append(item)
        
        return jsonify({
            "total": pagination.total,
            "pages": pagination.pages,
            "page": page,
            "per_page": per_page,
            "products": result
        }), 200

@api_v1.route('/inventory/stock/low', methods=['GET'])
@jwt_required()
def get_low_stock():
    """获取库存不足的商品"""
    threshold = request.args.get('threshold', 10, type=int)
    
    # 查找库存低于阈值的商品
    low_stock_products = Product.query.filter(Product.stock <= threshold).all()
    
    # 查找库存低于阈值的变体
    low_stock_variants = ProductVariant.query.filter(ProductVariant.stock <= threshold).all()
    
    # 构建结果
    result = {
        "products": [
            {
                "id": product.id,
                "name": product.name,
                "sku": product.sku,
                "stock": product.stock
            } for product in low_stock_products
        ],
        "variants": [
            {
                "id": variant.id,
                "product_id": variant.product_id,
                "product_name": Product.query.get(variant.product_id).name if Product.query.get(variant.product_id) else "",
                "sku": variant.sku,
                "specifications": variant.specifications,
                "stock": variant.stock
            } for variant in low_stock_variants
        ]
    }
    
    return jsonify(result), 200
